/********************************************************************
	created:	30:9:2007   20:43
	author:		tiamo
	purpose:	system control
*********************************************************************/

#include "stdafx.h"

GUID																	g_guidMSKeyboard_PortInformation = KEYBOARD_PORT_WMI_STD_DATA_GUID;
GUID																	g_guidMSKeyboard_ExtendedID = KEYBOARD_PORT_WMI_EXTENDED_ID;
WMIGUIDREGINFO g_wmiGuidAppleKeyboard[2] = 
{
	{&g_guidMSKeyboard_PortInformation,1,0},
	{&g_guidMSKeyboard_ExtendedID,1,0},
};

// system control
NTSTATUS AppleKeyboardSystemControl(__in PDEVICE_OBJECT pDeviceObject,__in PIRP pIrp)
{
	CDeviceExtension* pDevExt = static_cast<CDeviceExtension*>(pDeviceObject->DeviceExtension);

	AppleDebugPrint(DBGLEVEL_INFO,"Enter AppleKeyboardSystemControl %p,%p\n",pDeviceObject,pIrp);

	SYSCTL_IRP_DISPOSITION disposition;
	NTSTATUS statusRet = WmiSystemControl(&pDevExt->m_wmiLibContext,pDeviceObject,pIrp,&disposition);
	switch(disposition)
	{
	case IrpProcessed:
		break;

	case IrpNotCompleted:
		IoCompleteRequest(pIrp,IO_NO_INCREMENT);
		break;

	case IrpNotWmi:
	case IrpForward:
		IoSkipCurrentIrpStackLocation(pIrp);
		statusRet = IoCallDriver(pDevExt->m_pLowerDevice,pIrp);
		break;

	default:
		ASSERT(FALSE);
		break;
	}

	AppleDebugPrint(DBGLEVEL_INFO,"Leave AppleKeyboardSystemControl 0x%08x\n",statusRet);

	return statusRet;
}

// query wmi reg info
NTSTATUS AppleKeyboardQueryWmiRegInfo(__in PDEVICE_OBJECT pDeviceObject,__out PULONG pulRegFlags,__out PUNICODE_STRING pInstanceName,
									  __out PUNICODE_STRING *ppRegistryPath,__out PUNICODE_STRING pMofResourceName,__out PDEVICE_OBJECT *ppPdo)
{
	*ppRegistryPath = &g_regPath;
	*ppPdo = static_cast<CDeviceExtension*>(pDeviceObject->DeviceExtension)->m_pPhysicalDeviceObject;

	return STATUS_SUCCESS;
}

// query data block
NTSTATUS AppleKeyboardQueryWmiDataBlock(__in PDEVICE_OBJECT pDeviceObject,__in PIRP pIrp,__in ULONG ulGuidIndex,__in ULONG ulInstanceIndex,
										__in ULONG ulInstanceCount,__in __out PULONG pulInstanceLengthArray,__in ULONG ulBufferAvail,__out PUCHAR pBuffer)
{
	ASSERT(ulInstanceIndex == 0 && ulInstanceCount == 1);
	CDeviceExtension* pDevExt = static_cast<CDeviceExtension*>(pDeviceObject->DeviceExtension);
	NTSTATUS statusRet = STATUS_SUCCESS;
	ULONG ulBufferUsed = 0;

	switch(ulInstanceIndex)
	{
	case 0:
		ulBufferUsed = sizeof(KEYBOARD_PORT_WMI_STD_DATA);
		if(ulBufferAvail < ulBufferUsed)
		{
			statusRet = STATUS_BUFFER_TOO_SMALL;
		}
		else
		{
			PKEYBOARD_PORT_WMI_STD_DATA pData = static_cast<PKEYBOARD_PORT_WMI_STD_DATA>(static_cast<PVOID>(pBuffer));
			pData->ConnectorType = KEYBOARD_PORT_WMI_STD_USB;
			pData->DataQueueSize = pDevExt->m_attributeKeyboard.InputDataQueueLength;
			pData->ErrorCount = 0;
			pData->FunctionKeys = pDevExt->m_attributeKeyboard.NumberOfFunctionKeys;
			pData->Indicators = pDevExt->m_attributeKeyboard.NumberOfIndicators;

			*pulInstanceLengthArray = ulBufferUsed;
		}
		break;

	case 1:
		ulBufferUsed = sizeof(KEYBOARD_ID_EX);
		if(ulBufferAvail < ulBufferUsed)
		{
			statusRet = STATUS_BUFFER_TOO_SMALL;
		}
		else
		{
			RtlCopyMemory(pBuffer,&pDevExt->m_wmiKeyboardIdEx,ulBufferUsed);
			*pulInstanceLengthArray = ulBufferUsed;
		}
		break;

	default:
		statusRet = STATUS_WMI_GUID_NOT_FOUND;
	}

	return WmiCompleteRequest(pDeviceObject,pIrp,statusRet,ulBufferUsed,IO_NO_INCREMENT);
}

// set data block
NTSTATUS AppleKeyboardSetWmiDataBlock(__in PDEVICE_OBJECT pDeviceObject,__in PIRP pIrp,__in ULONG ulGuidIndex,__in ULONG ulInstanceIndex,
									  __in ULONG ulBufferSize,__in PUCHAR pBuffer)
{
	return WmiCompleteRequest(pDeviceObject,pIrp,ulGuidIndex == 1 ? STATUS_WMI_READ_ONLY : STATUS_WMI_GUID_NOT_FOUND,0,IO_NO_INCREMENT);
}

// set data item
NTSTATUS AppleKeyboardSetWmiDataItem(__in PDEVICE_OBJECT pDeviceObject,__in PIRP pIrp,__in ULONG ulGuidIndex,__in ULONG ulInstanceIndex,
									 __in ULONG ulDataItemId,__in ULONG ulBufferSize,__in PUCHAR pBuffer)
{
	return WmiCompleteRequest(pDeviceObject,pIrp,ulGuidIndex == 1 ? STATUS_WMI_READ_ONLY : STATUS_WMI_GUID_NOT_FOUND,0,IO_NO_INCREMENT);
}